﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Security;

using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Presenters;
using SharedGenomics.Workbench.Tests.TestObjects;

using Rhino.Mocks;
using Rhino.Mocks.Interfaces;

namespace SharedGenomics.Workbench.Tests.Presenters
{
    /// <summary>
    /// Summary description for LoginPresenterTests
    /// </summary>
    [TestClass]
    public class LoginPresenterTests
    {
        private MockRepository mocks;

        [TestInitialize]
        public void Setup()
        {
            this.mocks = new MockRepository();
        }

        [TestMethod]
        public void LoginSuccessful()
        {
            ILoginView view = MockRepository.GenerateStub<ILoginView>();
            var manager = new TestLoginManager() { LoginSucceeds = true };
            SecureString password = this.CreateSecureString("password");

            view.Stub(v => v.Username).Return("username");
            view.Stub(v => v.Password).Return(password);

            TestLoginPresenter p = new TestLoginPresenter(view, manager) { BackgroundExecutor = new TestBackgroundExecutor() };
            p.CallLogin();
            Assert.IsTrue(p.IsLoggedIn);
        }

        [TestMethod]
        public void LoginUnsuccessful()
        {
            ILoginView view = MockRepository.GenerateStub<ILoginView>();
            ILoginManager manager = new TestLoginManager { LoginSucceeds = false, LoginErrorMessage = "FAIL!" };
            SecureString password = this.CreateSecureString("password");

            TestLoginPresenter p = new TestLoginPresenter(view, manager) { BackgroundExecutor = new TestBackgroundExecutor() };
            p.CallLogin();
            Assert.IsFalse(p.IsLoggedIn);
        }

        private SecureString CreateSecureString(string str)
        {
            SecureString secStr = new SecureString();

            foreach (char c in str)
                secStr.AppendChar(c);

            secStr.MakeReadOnly();
            return secStr;
        }

        private class TestLoginPresenter : LoginPresenter
        {
            public TestLoginPresenter(ILoginView view, ILoginManager loginManager)
                : base(view, loginManager)
            {
            }

            public void CallLogin()
            {
                this.Login();
            }
        }

        private class TestLoginManager : ILoginManager
        {
            public bool IsLoggedIn { get; set; }
            public UserCredentials LoginCredentials { get; set; }

            public bool LoginSucceeds { get; set; }
            public string LoginErrorMessage { get; set; }

            public bool TryLogin(string userName, SecureString password, out string errorMessage)
            {
                errorMessage = this.LoginErrorMessage ?? String.Empty;
                return this.LoginSucceeds;
            }

            public event EventHandler IsLoggedInChanged;
        }
    }
}
